package com.aplink.generic.util;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.IBinder;

import java.util.List;
import java.util.Locale;

public class LocationTracker extends Service implements LocationListener {

    // The minimum distance to change Updates in meters
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10
    // meters

    // The minimum time between updates in milliseconds
    private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1
    // minute
    private String bestProvider;

    private Location location; // location

    // Declaring a Location Manager
    private LocationManager locationManager;

    private final Context mContext;

    public LocationTracker( Context context ) {
        this.mContext = context;
        // Get the location manager
        locationManager = null;
        locationManager = (LocationManager) mContext
                .getSystemService( LOCATION_SERVICE );
    }

    public boolean canGetLocation() {
        // flag for GPS status
        boolean isGPSEnabled = false;
        // flag for network status
        boolean isNetworkEnabled = false;
        // getting GPS status
        isGPSEnabled = locationManager
                .isProviderEnabled( LocationManager.GPS_PROVIDER );
        // getting network status
        isNetworkEnabled = locationManager
                .isProviderEnabled( LocationManager.NETWORK_PROVIDER );
        if ( isGPSEnabled == false && isNetworkEnabled == false ) {
            return false;
        } else {
            return true;
        }
    }

    public void continuetoGetLocation() {
        Criteria criteria = new Criteria();
        this.bestProvider = locationManager.getBestProvider( criteria, false ); // get
        // best
        // LOCATIONcheck
        // for
        // all
        // NETWORK
        this.locationManager.requestLocationUpdates( bestProvider,
                MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this );

    }

    public double[] getFromLocation( String address ) {

        double[] position = new double[2];
        Geocoder geoCoder = new Geocoder( this, Locale.getDefault() );
        /*
         * try { List<Address> addresses = geoCoder.getFromLocationName(address
		 * , 1); if (addresses.size() > 0) { position[0] =
		 * addresses.get(0).getLongitude(); position[1] =
		 * addresses.get(0).getLatitude(); } } catch(Exception ex){
		 * 
		 * }
		 */

        try {
            List<Address> geoResults = geoCoder.getFromLocationName( address, 1 );
            while ( geoResults.size() == 0 ) {
                geoResults = geoCoder.getFromLocationName( address, 1 );

                if ( geoResults.size() > 0 ) {
                    Address addr = geoResults.get( 0 );
                    position[1] = addr.getLatitude();
                    position[0] = addr.getLongitude();

                    if ( position[1] != 0.0 && position[0] != 0.0 ) {
                        return position;
                    }
                }
            }
        } catch ( Exception e ) {
            System.out.print( e.getMessage() );
        }

        return position;
    }

    public double getLatitude() {
        if ( this.location != null ) {
            return this.location.getLatitude();
        } else {
            return 0.0;
        }
    }

    public Location getLocation() {

        // we check to download map
        ConnectivityManager cm = (ConnectivityManager) mContext
                .getSystemService( Context.CONNECTIVITY_SERVICE );
        NetworkInfo ni = cm.getActiveNetworkInfo();
        if ( null == ni ) {
            return null;
        }

        if ( ni.isConnectedOrConnecting() == false ) {
            return null;
        }

        // we then get the best LOCATION PROVIDER WHETHER THAT IS NETWORK OR GPS
        Criteria criteria = new Criteria();
        criteria.setAccuracy( Criteria.ACCURACY_FINE );

        // refresh locationManager
        locationManager = (LocationManager) mContext
                .getSystemService( LOCATION_SERVICE );

        this.bestProvider = locationManager.getBestProvider( criteria, true );
        this.locationManager.requestLocationUpdates( bestProvider,
                MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this );
        this.location = locationManager.getLastKnownLocation( bestProvider );
        return this.location;
    }

    public double getLongtitude() {
        if ( this.location != null ) {
            return this.location.getLongitude();
        } else {
            return 0.0;
        }
    }

    @Override
    public IBinder onBind( Intent arg0 ) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onLocationChanged( Location arg0 ) {
        // TODO Auto-generated method stub
        // printLocation(location);
        this.location = arg0;
        // we need to invoke again
    }

    @Override
    public void onProviderDisabled( String provider ) {
        // TODO Auto-generated method stub
        // output.append("\n\nProvider Disabled: " + provider);
    }

    @Override
    public void onProviderEnabled( String provider ) {
        // TODO Auto-generated method stub
        // output.append("\n\nProvider Enabled: " + provider);
    }

    @Override
    public void onStatusChanged( String provider, int status, Bundle extras ) {
        // TODO Auto-generated method stub
        // output.append("\n\nProvider Status Changed: " + provider +
        // ", Status="
        // + S[status] + ", Extras=" + extras);
    }

    public void stopUsingTracker() {
        if ( locationManager != null ) {
            locationManager.removeUpdates( LocationTracker.this );
        }
    }
}
